// 用react实现：
// 默认情况下，红灯亮20秒，并且最后5秒闪烁
// 绿灯亮20秒，并且最后5秒闪烁
// 黄灯亮10秒， 
// 次序为：红-绿-黄-红-绿-黄。 
// 灯的个数、颜色、持续时间、闪烁时间、灯光次序都可配置，
// 如：lights=[{color: '#fff', duration: 10000, twinkleDuration: 5000}, ... ]


import React, { useState, useEffect, useRef } from 'react';
import ReactDOM from 'react-dom/client';


const TrafficLight = ({ lights }) => {
  // 记录当前亮起的灯在 lights 数组中的索引
  const [currentIndex, setCurrentIndex] = useState(0);
  // 当前灯剩余的点亮时间，初始值为当前灯的持续时间
  const [remainingTime, setRemainingTime] = useState(lights[currentIndex].duration);
  // 存储定时器的引用，方便在组件卸载时清除定时器，避免内存泄漏
  const timerRef = useRef(null);

  // currentIndex 或 lights 数组变化时执行副作用操作
  useEffect(() => {
    // startTimer 函数用于启动定时器
    const startTimer = () => {
      // 每秒执行一次回调函数
      timerRef.current = setInterval(() => {
        // 更新剩余时间
        setRemainingTime(prevTime => {
          // 如果剩余时间大于 1 秒，将剩余时间减 1 秒
          if (prevTime > 1000) {
            return prevTime - 1000;
          } else {
            // 当剩余时间小于等于 1 秒时，清除定时器
            clearInterval(timerRef.current);
            // 切换到下一个灯，使用取模运算确保索引在 lights 数组范围内
            setCurrentIndex(prevIndex => (prevIndex + 1) % lights.length);
            // 设置新灯的剩余时间为其持续时间
            setRemainingTime(lights[(prevIndex + 1) % lights.length].duration);
            return lights[(prevIndex + 1) % lights.length].duration;
          }
        });
      }, 1000);
    };

    // 启动定时器
    startTimer();

    // 组件卸载时的清理函数，清除定时器
    return () => {
      clearInterval(timerRef.current);
    };
  }, [currentIndex, lights]);

  // 判断当前灯是否处于闪烁状态，即剩余时间小于等于闪烁时间
  const isTwinkling = remainingTime <= lights[currentIndex].twinkleDuration;
  // 根据是否闪烁和时间来控制灯的透明度，实现闪烁效果
  const opacity = isTwinkling && remainingTime % 2000 < 1000 ? 0.2 : 1;


  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      {/* 遍历 lights 数组，渲染每个灯 */}
      {lights.map((light, index) => (
        <div
          key={index}
          style={{
            width: 50,
            height: 50,
            borderRadius: '50%',
            backgroundColor: light.color,
            // 当前亮起的灯根据是否闪烁设置透明度，其他灯透明度为 0.2
            opacity: index === currentIndex ? opacity : 0.2,
            margin: 10
          }}
        />
      ))}
      {/* 显示当前灯的颜色和剩余时间 */}
      <p>当前灯: {lights[currentIndex].color}，剩余时间: {remainingTime / 1000} 秒</p>
    </div>
  );
};

// App 组件是应用的根组件，用于配置交通灯并渲染 TrafficLight 组件
const App = () => {
  // 定义交通灯的配置数组，包含每个灯的颜色、持续时间和闪烁时间
  const lights = [
    { color: 'red', duration: 20000, twinkleDuration: 5000 },
    { color: 'green', duration: 20000, twinkleDuration: 5000 },
    { color: 'yellow', duration: 10000, twinkleDuration: 0 }
  ];

  return (
    <div>
      <h1>可配置交通灯</h1>
      {/* 渲染 TrafficLight 组件，并传入 lights 数组 */}
      <TrafficLight lights={lights} />
    </div>
  );
};

// 创建 React 根节点，将 App 组件渲染到页面上 id 为 root 的元素中
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
